#include "Cube.h"
#include "HelperD3D.h"
#include "DirectX11.h"
#include "VertexShader.csh"
#include "PixelShader.csh"


//Cube::Cube(void)
//{
//	ID3D11Device* device = DirectX11::GetInstance()->GetDevice();
//
//	XMFLOAT3* positions;
//	XMFLOAT3* normals;
//	XMFLOAT2* uvs;
//	XMFLOAT2* tangents;
//	UINT* indices;
//	CreateCube(5, &positions, &normals, &uvs, &tangents, &indices);
//
//	RenderInfo data;
//	data.numIndices = 6;
//	data.numVerts = 6;
//	data.numBuffers = 4;
//	data.topology = D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
//
//	D3D11_BUFFER_DESC desc;
//	desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
//	desc.Usage = D3D11_USAGE_IMMUTABLE;
//	desc.CPUAccessFlags = NULL;
//	desc.ByteWidth = sizeof(XMFLOAT3)* 4;
//	desc.MiscFlags = NULL;
//
//	D3D11_SUBRESOURCE_DATA init;
//	init.pSysMem = positions;
//	init.SysMemPitch = init.SysMemSlicePitch = 0;
//
//	HRESULT hr = device->CreateBuffer(&desc, &init, &data.buffers[POS]);
//	ERRORCHECK(hr, L"ERROR: Failed to create positions buffer RENDERABLE");
//
//	init.pSysMem = normals;
//	hr = device->CreateBuffer(&desc, &init, &data.buffers[NORM]);
//	ERRORCHECK(hr, L"ERROR: Failed to create normals buffer RENDERABLE");
//
//	desc.ByteWidth = sizeof(XMFLOAT2)* 4;
//	init.pSysMem = tangents;
//	hr = device->CreateBuffer(&desc, &init, &data.buffers[TAN]);
//	ERRORCHECK(hr, L"ERROR: Failed to create tangents buffer RENDERABLE");
//
//	init.pSysMem = uvs;
//	hr = device->CreateBuffer(&desc, &init, &data.buffers[UV]);
//	ERRORCHECK(hr, L"ERROR: Failed to create uvs buffer RENDERABLE");
//
//	desc.BindFlags = D3D11_BIND_INDEX_BUFFER;
//	desc.ByteWidth = sizeof(UINT)* 6;
//	init.pSysMem = indices;
//	hr = device->CreateBuffer(&desc, &init, &data.indexBuffer);
//	ERRORCHECK(hr, L"ERROR: Failed to create indices buffer RENDERABLE");
//
//	data.strides[0] = sizeof(XMFLOAT3);
//	data.strides[1] = data.strides[0];
//	data.strides[2] = sizeof(XMFLOAT2);
//	data.strides[3] = data.strides[2];
//
//	data.offsets[0] = data.offsets[1] = data.offsets[2] = data.offsets[3] = 0;
//
//	hr = device->CreateVertexShader(VertexShader, sizeof(VertexShader), NULL, &data.vs);
//	ERRORCHECK(hr, L"ERROR: Failed to Create Vertex Shader\n\tMay be due to problem in shader");
//
//	hr = device->CreatePixelShader(PixelShader, sizeof(PixelShader), NULL, &data.ps);
//	ERRORCHECK(hr, L"ERROR: Failed to Create Vertex Shader\n\tMay be due to problem in shader");
//
//	//Create Input Layouts...
//	D3D11_INPUT_ELEMENT_DESC layout[] = {
//		{ LPCSTR("POSITION"), 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA },
//		{ LPCSTR("NORMAL"), 0, DXGI_FORMAT_R32G32B32_FLOAT, 1, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA },
//		{ LPCSTR("TEXCOORD"), 0, DXGI_FORMAT_R32G32_FLOAT, 2, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA },
//		{ LPCSTR("TANGENT"), 0, DXGI_FORMAT_R32G32_FLOAT, 3, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA }
//	};
//
//	hr = device->CreateInputLayout(layout, ARRAYSIZE(layout), VertexShader, sizeof(VertexShader), &data.inputLayout);
//	ERRORCHECK(hr, L"ERROR: Failed to create input layout");
//
//	//Create Buffers...
//	ZeroMemory(&desc, sizeof(D3D11_BUFFER_DESC));
//	desc.Usage = D3D11_USAGE_DYNAMIC;
//	desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
//	desc.MiscFlags = 0;
//	desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
//	desc.ByteWidth = sizeof(OBJECT);
//	desc.StructureByteStride = 0;
//
//	D3D11_SUBRESOURCE_DATA init_data;
//	ZeroMemory(&init_data, sizeof(D3D11_SUBRESOURCE_DATA));
//	init_data.pSysMem = &data.object;
//	init_data.SysMemPitch = 0;
//	init_data.SysMemSlicePitch = 0;
//
//	hr = device->CreateBuffer(&desc, &init_data, &data.objectCB);
//	ERRORCHECK(hr, L"ERROR: Failed to create Object CB");
//
//	XMStoreFloat4x4(&data.object.mWorld,XMMatrixIdentity());
//
//	renderData.SetRenderData(data);
//	renderData.LoadTexture(L"182.dds");
//
//
//	delete [] positions;
//	delete [] normals;
//	delete [] uvs;
//	delete [] tangents;
//	delete [] indices;
//}

Cube::Cube(XMFLOAT4 initialPosition /*= PosXYZ(0,0,0)*/)
{
	ID3D11Device* device = DirectX11::GetInstance()->GetDevice();

	XMFLOAT3* positions;
	XMFLOAT3* normals;
	XMFLOAT2* uvs;
	XMFLOAT2* tangents;
	UINT* indices;
	CreateCube(5, &positions, &normals, &uvs, &tangents, &indices);

	RenderInfo data;
	data.numIndices = 6;
	data.numVerts = 6;
	data.numBuffers = 4;
	data.topology = D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST;

	D3D11_BUFFER_DESC desc;
	desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
	desc.Usage = D3D11_USAGE_IMMUTABLE;
	desc.CPUAccessFlags = NULL;
	desc.ByteWidth = sizeof(XMFLOAT3)* 4;
	desc.MiscFlags = NULL;

	D3D11_SUBRESOURCE_DATA init;
	init.pSysMem = positions;
	init.SysMemPitch = init.SysMemSlicePitch = 0;

	HRESULT hr = device->CreateBuffer(&desc, &init, &data.buffers[POS]);
	ERRORCHECK(hr, L"ERROR: Failed to create positions buffer RENDERABLE");

	init.pSysMem = normals;
	hr = device->CreateBuffer(&desc, &init, &data.buffers[NORM]);
	ERRORCHECK(hr, L"ERROR: Failed to create normals buffer RENDERABLE");

	desc.ByteWidth = sizeof(XMFLOAT2)* 4;
	init.pSysMem = tangents;
	hr = device->CreateBuffer(&desc, &init, &data.buffers[TAN]);
	ERRORCHECK(hr, L"ERROR: Failed to create tangents buffer RENDERABLE");

	init.pSysMem = uvs;
	hr = device->CreateBuffer(&desc, &init, &data.buffers[UV]);
	ERRORCHECK(hr, L"ERROR: Failed to create uvs buffer RENDERABLE");

	desc.BindFlags = D3D11_BIND_INDEX_BUFFER;
	desc.ByteWidth = sizeof(UINT)* 6;
	init.pSysMem = indices;
	hr = device->CreateBuffer(&desc, &init, &data.indexBuffer);
	ERRORCHECK(hr, L"ERROR: Failed to create indices buffer RENDERABLE");

	data.strides[0] = sizeof(XMFLOAT3);
	data.strides[1] = data.strides[0];
	data.strides[2] = sizeof(XMFLOAT2);
	data.strides[3] = data.strides[2];

	data.offsets[0] = data.offsets[1] = data.offsets[2] = data.offsets[3] = 0;

	hr = device->CreateVertexShader(VertexShader, sizeof(VertexShader), NULL, &data.vs);
	ERRORCHECK(hr, L"ERROR: Failed to Create Vertex Shader\n\tMay be due to problem in shader");

	hr = device->CreatePixelShader(PixelShader, sizeof(PixelShader), NULL, &data.ps);
	ERRORCHECK(hr, L"ERROR: Failed to Create Vertex Shader\n\tMay be due to problem in shader");

	//Create Input Layouts...
	D3D11_INPUT_ELEMENT_DESC layout[] = {
		{ LPCSTR("POSITION"), 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA },
		{ LPCSTR("NORMAL"), 0, DXGI_FORMAT_R32G32B32_FLOAT, 1, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA },
		{ LPCSTR("TEXCOORD"), 0, DXGI_FORMAT_R32G32_FLOAT, 2, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA },
		{ LPCSTR("TANGENT"), 0, DXGI_FORMAT_R32G32_FLOAT, 3, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA }
	};

	hr = device->CreateInputLayout(layout, ARRAYSIZE(layout), VertexShader, sizeof(VertexShader), &data.inputLayout);
	ERRORCHECK(hr, L"ERROR: Failed to create input layout");

	//Create Buffers...
	ZeroMemory(&desc, sizeof(D3D11_BUFFER_DESC));
	desc.Usage = D3D11_USAGE_DYNAMIC;
	desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
	desc.MiscFlags = 0;
	desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
	desc.ByteWidth = sizeof(OBJECT);
	desc.StructureByteStride = 0;

	D3D11_SUBRESOURCE_DATA init_data;
	ZeroMemory(&init_data, sizeof(D3D11_SUBRESOURCE_DATA));
	init_data.pSysMem = &data.object;
	init_data.SysMemPitch = 0;
	init_data.SysMemSlicePitch = 0;

	hr = device->CreateBuffer(&desc, &init_data, &data.objectCB);
	ERRORCHECK(hr, L"ERROR: Failed to create Object CB");

	XMStoreFloat4x4(&data.object.mWorld,XMMatrixIdentity());
	XMMATRIX world = XMLoadFloat4x4(&data.object.mWorld);
	XMMATRIX translation = XMMatrixTranslation(initialPosition.x,initialPosition.y,initialPosition.z);
	world = XMMatrixMultiply(translation,world);
	XMStoreFloat4x4(&data.object.mWorld,world);


	renderData.SetRenderData(data);
	renderData.LoadTexture(L"182.dds");


	delete [] positions;
	delete [] normals;
	delete [] uvs;
	delete [] tangents;
	delete [] indices;
}


Cube::~Cube(void)
{
}
